<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务，帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2024 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace app\common\library\eOrder\provider\driver;

use app\common\library\eOrder\provider\Driver;
use app\common\library\helper;
use cores\exception\BaseException;

/**
 * 快递100驱动
 * Class Kd100
 * @package app\common\library\eOrder\provider\driver
 */
class Kd100 extends Driver
{
    // API地址
    const API_URL = 'https://poll.kuaidi100.com/eorderapi.do?method=getElecOrder';

    /**
     * 获取电子面单内容 (HTML格式)
     * @throws BaseException
     */
    public function handle(): array
    {
        $result = $this->getElecOrder();
        return [
            // 快递单号
            'expressNo' => $result['kuaidinum'],
            // 电子面单模板内容 (html)
            'content' => $result['template'][0],
        ];
    }

    /**
     * API：获取电子面单内容
     * @return array|mixed
     * @throws BaseException
     */
    public function getElecOrder()
    {
        // API参数设置
        $key = $this->options['kd100']['key'];           // 客户授权key
        $secret = $this->options['kd100']['secret'];     // 授权secret
        // 当前时间戳
        [$msec, $sec] = explode(' ', microtime());
        $t = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
        // 请求参数
        $param = [
            'partnerId' => $this->eleTemplate['customerName'],      // 电子面单客户账户或月结账号
            'partnerKey' => $this->eleTemplate['customerPwd'],      // 电子面单密码
            'net' => $this->eleTemplate['sendSite'],                // 收件网点名称, 由快递公司当地网点分配
            'kuaidicom' => $this->eleTemplate['shipperCode'],       // 快递公司的编码
            'recMan' => [
                'name' => $this->receiver['name'],                   // 收件人姓名
                'mobile' => $this->receiver['mobile'],               // 收件人手机
                'printAddr' => $this->printAddr($this->receiver),    // 收件人地址
                'company' => ''                                      // 收件人公司名
            ],
            'sendMan' => [
                'name' => $this->sender['name'],                    // 寄件人姓名
                'mobile' => $this->sender['mobile'],                // 寄件人手机
                'printAddr' => $this->printAddr($this->sender),     // 寄件人地址
                'company' => ''                                     // 寄件人公司名
            ],
            'cargo' => $this->cargo(),                      // 物品名称
            'count' => '',                                  // 物品总数量
            'weight' => $this->deliverOrder['weight'],      // 物品总重量
            'payType' => $this->eleTemplate['payType'],         // 支付方式
            'expType' => '标准快递',             // 快递类型: 标准快递（默认）、顺丰特惠、EMS经济
            'remark' => '',                    // 备注
            'needTemplate' => '1'              // 是否返回面单：0：不开启(默认)、1：开启
        ];
        // 请求参数
        $postData = [];
        $postData["param"] = json_encode($param, JSON_UNESCAPED_UNICODE);
        $postData["key"] = $key;
        $postData["t"] = $t;
        $postData["sign"] = strtoupper(md5($postData["param"] . $t . $key . $secret));
        // 发送post请求
        $result = $this->curlPost(self::API_URL, $postData);
        // 处理返回结果
        $data = helper::jsonDecode($result);
        // 记录日志
        log_record(['name' => '电子面单API', 'provider' => 'kd100', 'param' => $param, 'result' => $data]);
        // 判断请求状态
        if (!$data['result'] || $data['status'] != 200) {
            throwError('快递100API请求失败：' . ($data['message'] ?? '-'));
        }
        return $data['data'][0];
    }

    /**
     * 转义商品数据
     * @return string
     */
    private function cargo(): string
    {
        $goodsItem = reset($this->deliverOrder['commodity']);
        return $goodsItem['goodsName'] . (!empty($goodsItem['goodsProps']) ? "【{$goodsItem['goodsProps']}】" : '');
    }

    /**
     * 格式化完整的地址
     * @param array $data
     * @return string
     */
    private function printAddr(array $data): string
    {
        return "{$data['provinceName']}{$data['cityName']}{$data['expAreaName']}{$data['address']}";
    }
}